% TEST_ID: LANG-EXPAND-0076
% CATEGORY: stdlib/arithmetic_ops/subtraction
% 测试 diff 函数


function test_diff
    X = [
        0.3558 0.5738 0.5227 0.7302 0.7532

        0.3908 0.14 0.1279 0.2395 0.4357

        0.6337 0.1061 0.7636 0.2748 0.2744
    ];

    assert(isclose(diff(X), [
        0.0350 -0.4338 -0.3948 -0.4907 -0.3175
        0.2429 -0.0339 0.6357 0.0353 -0.1613
    ]));


    assert(isclose(diff(X, 2), [
        0.2079 0.3999 1.0305 0.5260 0.1562
    ]));

    assert(isclose(diff(X, []), [
        0.0350 -0.4338 -0.3948 -0.4907 -0.3175
        0.2429 -0.0339 0.6357 0.0353 -0.1613
    ]));

    assert(isclose(diff(X, 3, 2), [
        0.527700000000000 -0.443100000000000
        -0.115000000000000 -0.039100000000000
        -2.331400000000000 1.634700000000000
    ]));

    h = 0.001; % step size
    X = -pi:h:pi; % domain
    f = sin(X); % range
    Y = diff(f) / h; % first derivative
    Z = diff(Y) / h; % second derivative

    assert(isclose(median(Z), 9.265357037158140e-05, 1e-4))
    assert(isclose(mean(Z), 1.748216377067338e-08))

    assert(isclose(mean(Y), 2.949342328914033e-05))
    assert(isclose(median(Y), -1.110196105047478e-04))

    assert(diff(int64([3 4])) == 1)
    assert(diff(int32([3 4])) == 1)
    assert(diff(int16([3 4])) == 1)
    assert(diff(int8([3 4])) == 1)
    assert(diff(uint64([3 4])) == 1)
    assert(diff(uint32([3 4])) == 1)
    assert(diff(uint16([3 4])) == 1)
    assert(diff(uint8([3 4])) == 1)
    assert(diff([true false]) == -1)

    assert(diff(uint64([5 4])) == 0)
    assert(diff(uint32([5 4])) == 0)
    assert(diff(uint16([5 4])) == 0)
    assert(diff(uint8([5 4])) == 0)
    assert(diff(int8([-5 127])) == 127)
    class(diff(int16([-5 127])))
end

function r = isclose(X, Y, precision)
    if nargin < 3
        precision = 1e-6;
    end
    r = all(abs(X - Y) < precision, 'all');
end
